#pragma once

#include <set>
#include <string>

namespace avlib{

	//String^ marshals to const char* unless a [MarshalAs] attribute is applied to the delegate argument. 
typedef void (__stdcall* VideoDeviceCallback)(int vid,const char *devname);
typedef void (__stdcall* AudioDeviceCallback)(int vid,const char *devname);
typedef void (__stdcall* RecordProgressCallback)(int frame,int samplecount);
typedef void (__stdcall* RecordErrorCallback)(int errno,const char *err_str);


class System;
class AudioRecorder;
class VideoRecorder;
class ScreenRecorder;
class AviFile;





class AVRecorder{
private:
		System *sys;
		AudioRecorder *a_corder;
		ScreenRecorder *s_corder;
		VideoRecorder *v_corder;
		AviFile		*avi;

		std::string thumb_file;
		bool capture_screen;

		//state
		/*bool bRecording;

		int nFrame; //video frame count
		int nSample; //audio sample count*/

		//options
		unsigned fps;
		RECT region;

		//callbacks
		VideoDeviceCallback vdev_cb;
		AudioDeviceCallback adev_cb;

		RecordProgressCallback prog_cb;
		RecordErrorCallback	   err_cb;

		HANDLE hWaveInThread;
		//DbgGuiLeak gui_leak;
public:
		HANDLE  closeEvent;
		AVRecorder();
		~AVRecorder();
		
		//main api
		bool init(VideoDeviceCallback vdev_cb,AudioDeviceCallback adev_cb);
		
		bool record(int vid,int aid,std::string& avi,std::string &thumbnail,HWND hwnd);
		bool stop();

		void window_resized(HWND hwnd);
		void on_progress( int frame,int sample);	
		//set options
		void set_fps(unsigned fps){
			this->fps = fps;
		}
		//helper function
		unsigned get_fps(){
			return this->fps;
		}

		float get_duration();
		WAVEFORMATEX * get_audio_format();

		bool is_recording();

		void set_record_callback(RecordProgressCallback prog_cb,RecordErrorCallback err_cb){
			this->prog_cb = prog_cb;
			this->err_cb = err_cb;
		}

		void set_rect(int left,int top,int width,int height);

		bool query_dimension(int idx,std::set<unsigned long> & dims);
};
};
